{
libxl_free_all(ctx);
free(ctx->alloc_ptrs);
- ctx->alloc_ptrs = NULL;
+ ctx->alloc_ptrs = calloc(ctx->alloc_maxsize, sizeof(void *));
+ if (!ctx->alloc_ptrs)
+ return ERROR_NOMEM;
+ return 0;
+}
+
+int libxl_ctx_close(struct libxl_ctx *ctx)
+{
+ libxl_ctx_free(ctx);
+ free(ctx->alloc_ptrs);
xc_interface_close(ctx->xch);
- xs_daemon_close(ctx->xsh);
+ xs_daemon_close(ctx->xsh);
return 0;
}
return 0;
}
+int libxl_wait_for_domain_death(struct libxl_ctx *ctx, uint32_t domid, int *fd)
+{
+ if (!xs_watch(ctx->xsh, "@releaseDomain", "domain_death"))
+ return -1;
+ *fd = xs_fileno(ctx->xsh);
+ return 0;
+}
+
+int libxl_is_domain_dead(struct libxl_ctx *ctx, uint32_t domid, xc_dominfo_t *info)
+{
+ unsigned int num;
+ int nb_domain, i, rc = 0;
+ char **vec = NULL;
+ xc_dominfo_t *list = NULL;
+
+ vec = xs_read_watch(ctx->xsh, &num);
+ if (!vec)
+ return 0;
+ if (!strcmp(vec[XS_WATCH_TOKEN], "domain_death")) {
+ list = libxl_domain_infolist(ctx, &nb_domain);
+ for (i = 0; i < nb_domain; i++) {
+ if (domid == list[i].domid) {
+ if (list[i].running || (!list[i].shutdown && !list[i].crashed && !list[i].dying))
+ goto out;
+ *info = list[i];
+ rc = 1;
+ goto out;
+ }
+ }
+ memset(info, 0x00, sizeof(xc_dominfo_t));
+ rc = 1;
+ goto out;
+ }
+
+out:
+ free(list);
+ free(vec);
+ return rc;
+}
+
static int libxl_destroy_device_model(struct libxl_ctx *ctx, uint32_t domid)
{
char *pid;
}
if (libxl_destroy_device_model(ctx, domid) < 0)
XL_LOG(ctx, XL_LOG_ERROR, "libxl_destroy_device_model failed for %d", domid);
- rc = xc_domain_destroy(ctx->xch, domid);
- if (rc < 0) {
- XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "xc_domain_destroy failed for %d", domid);
- return -1;
- }
if (libxl_devices_destroy(ctx, domid, force) < 0)
XL_LOG(ctx, XL_LOG_ERROR, "libxl_destroy_devices failed for %d", domid);
if (!xs_rm(ctx->xsh, XBT_NULL, dom_path))
snprintf(vm_path, sizeof(vm_path), "/vm/%s", libxl_uuid_to_string(ctx, uuid));
if (!xs_rm(ctx->xsh, XBT_NULL, vm_path))
XL_LOG_ERRNO(ctx, XL_LOG_ERROR, "xs_rm failed for %s", vm_path);
+ rc = xc_domain_destroy(ctx->xch, domid);
+ if (rc < 0) {
+ XL_LOG_ERRNOVAL(ctx, XL_LOG_ERROR, rc, "xc_domain_destroy failed for %d", domid);
+ return -1;
+ }
return 0;
}
/* context functions */
int libxl_ctx_init(struct libxl_ctx *ctx);
int libxl_ctx_free(struct libxl_ctx *ctx);
+int libxl_ctx_close(struct libxl_ctx *ctx);
int libxl_ctx_set_log(struct libxl_ctx *ctx, libxl_log_callback log_callback, void *log_data);
/* domain related functions */
int libxl_domain_shutdown(struct libxl_ctx *ctx, uint32_t domid, int req);
int libxl_domain_destroy(struct libxl_ctx *ctx, uint32_t domid, int force);
+int libxl_wait_for_domain_death(struct libxl_ctx *ctx, uint32_t domid, int *fd);
+int libxl_is_domain_dead(struct libxl_ctx *ctx, uint32_t domid, xc_dominfo_t *info);
+
int libxl_domain_pause(struct libxl_ctx *ctx, uint32_t domid);
int libxl_domain_unpause(struct libxl_ctx *ctx, uint32_t domid);
#include <sys/time.h> /* for time */
#include <getopt.h>
#include <sys/types.h>
+#include <sys/stat.h>
+#include <fcntl.h>
#include <sys/socket.h>
+#include <sys/select.h>
#include <arpa/inet.h>
#include <xenctrl.h>
libxl_device_vkb *vkbs = NULL;
libxl_device_console console;
int num_disks = 0, num_vifs = 0, num_pcidevs = 0, num_vfbs = 0, num_vkbs = 0;
- int i;
+ int i, fd;
+ int need_daemon = 1;
libxl_device_model_starting *dm_starting = 0;
printf("Parsing config file %s\n", filename);
if (debug)
printf_info(&info1, &info2, disks, num_disks, vifs, num_vifs, pcidevs, num_pcidevs, vfbs, num_vfbs, vkbs, num_vkbs, &dm_info);
+start:
+ domid = 0;
+
libxl_ctx_init(&ctx);
libxl_ctx_set_log(&ctx, log_callback, NULL);
libxl_domain_make(&ctx, &info1, &domid);
libxl_domain_unpause(&ctx, domid);
+ if (need_daemon) {
+ daemon(0, 0);
+ need_daemon = 0;
+ }
+
+ libxl_wait_for_domain_death(&ctx, domid, &fd);
+ while (1) {
+ int ret;
+ fd_set rfds;
+ xc_dominfo_t info;
+ memset(&info, 0x00, sizeof(xc_dominfo_t));
+
+ FD_ZERO(&rfds);
+ FD_SET(fd, &rfds);
+
+ ret = select(fd + 1, &rfds, NULL, NULL, NULL);
+ if (!ret)
+ continue;
+ if (libxl_is_domain_dead(&ctx, domid, &info)) {
+ if (info.crashed || info.dying || (info.shutdown && (info.shutdown_reason != SHUTDOWN_suspend))) {
+ libxl_domain_destroy(&ctx, domid, 0);
+ if (info.shutdown && (info.shutdown_reason == SHUTDOWN_reboot)) {
+ libxl_ctx_free(&ctx);
+ goto start;
+ }
+ }
+ exit(0);
+ }
+ }
+
for (i = 0; i < num_vifs; i++) {
free(vifs[i].smac);
free(vifs[i].ifname);